package cn.edu.cug.cs.gtl.gsm.aof.ftp;

import cn.edu.cug.cs.gtl.common.Identifier;
import cn.edu.cug.cs.gtl.gsm.aof.AOFStorageManager;
import cn.edu.cug.cs.gtl.gsm.aof.DataFiles;
import cn.edu.cug.cs.gtl.gsm.aof.IndexFile;
import cn.edu.cug.cs.gtl.gsm.item.MetaItem;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
public class FTPStorageManager  extends AOFStorageManager{
    protected static String host = "121.37.219.134";
    protected static String password = "123456@Cug";
    protected static int port = 21;
    protected static String user ="ftp";
    protected FTPClient ftpClient;

    /**
     * @param workDirectory
     * @param baseName
     * @param collectionSize
     * @param pageSize
     * @param overwrite
     */
    public FTPStorageManager(FTPClient ftpClient, String workDirectory, String baseName, long collectionSize, int pageSize, boolean overwrite) throws IOException {
        super(workDirectory, baseName, collectionSize, pageSize, overwrite);
        this.ftpClient=ftpClient;
        initial(overwrite);
    }

    @Override
    protected void closeStorages() throws IOException {
        ftpClient.disconnect();
    }
    @Override
    public IndexFile createIndexFile() {
        return new FTPIndexFile(ftpClient,workDirectory,metaItem,pageMap);
    }

    @Override
    public DataFiles createDataFiles() {
        return new FTPDataFiles(ftpClient,workDirectory,metaItem,pageMap);
    }


    /**
     * 在workDirectory下创建baseName目录,并返回全路径目录，系统将在baseName目录下建立索引文件和数据文件
     *
     * @param workDirectory
     * @param baseName
     * @return
     * @throws IOException
     */
    @Override
    public boolean createDirectory(String workDirectory, String baseName) throws IOException {
        return createDirectory(ftpClient,workDirectory,baseName);
    }

    @Override
    public boolean existsFile(String fullPathName) throws IOException {
        return existsFile(this.ftpClient, fullPathName);
    }

    @Override
    public boolean existsDirectory(String fullPath) throws IOException {
        return existsDirectory(ftpClient,fullPath);
    }


    @Override
    public boolean existsDirectory(String workDirectory, String baseName) throws IOException {
        return existsDirectory(ftpClient,workDirectory,baseName);
    }

    /**
     * FTP目录拼接
     * @param workDirectory
     * @param baseName
     * @return
     */
    public static String concatenate(String workDirectory, String baseName){
        if(workDirectory.endsWith("/"))
            return (workDirectory+baseName);
        else
            return (workDirectory+"/"+baseName);
    }

    /**
     * FTP目录、文件名拼接
     * @param workDirectory
     * @param baseName
     * @param fileName
     * @return
     */
    public static String concatenate(String workDirectory, String baseName, String fileName){
        String dir = concatenate(workDirectory,baseName);
        if(dir.endsWith("/"))
            return (dir+fileName);
        else
            return (dir+"/"+fileName);
    }
    /**
     *
     * @param ftpClient
     * @param workDirectory
     * @param baseName
     * @return
     * @throws IOException
     */
    public static boolean createDirectory(FTPClient ftpClient, String workDirectory, String baseName) throws IOException {
        return ftpClient.makeDirectory(concatenate(workDirectory,baseName));
    }


    /**
     * 判断文件是否存在
     * @param ftpClient
     * @param fullPathName 目录+文件名
     * @return
     * @throws IOException
     */
    public static boolean existsFile(FTPClient ftpClient,String fullPathName) throws IOException {
        String[] listNames = ftpClient.listNames(fullPathName);
        if(listNames==null) return false;
        boolean existsFlag = listNames.length > 0;
        return existsFlag;
    }

    /**
     * 判断目录是否存在
     * @param ftpClient
     * @param fullPath
     * @return
     * @throws IOException
     */
    public static boolean existsDirectory(FTPClient ftpClient,String fullPath) throws IOException {
        String[] listNames = ftpClient.listNames(fullPath);
        if(listNames==null) return false;
        boolean existsFlag = listNames.length > 0;
        return existsFlag;
    }

    /**
     * 判断拼接后的目录是否存在
     * @param ftpClient
     * @param workDirectory
     * @param baseName
     * @return
     * @throws IOException
     */
    public static boolean existsDirectory(FTPClient ftpClient,String workDirectory, String baseName) throws IOException {
        return existsDirectory(ftpClient,concatenate(workDirectory,baseName));
    }

    /**
     * 获取FTP连接
     * @param host
     * @param port
     * @param username
     * @param password
     * @param fileType  0-FTP.ASCII_FILE_TYPE  2-FTP.BINARY_FILE_TYPE
     * @return
     * @throws IOException
     */
    public static FTPClient getConnection(
            String host, int port, String username, String password,
            int fileType) throws IOException {
        FTPClient ftpClient = new FTPClient();
        ftpClient.connect(host, port); // 连接ftp服务器
        ftpClient.setConnectTimeout(0);
        ftpClient.setControlKeepAliveTimeout(3600);
        // 设置以字节流传输模式
        ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
        // 设置为被动模式登陆
        ftpClient.enterLocalPassiveMode();
        ftpClient.setAutodetectUTF8(true);
        ftpClient.setFileType(fileType);
        ftpClient.login(username, password); // 登录ftp服务器
        int replyCode = ftpClient.getReplyCode(); // 是否成功登录服务器
        if (!FTPReply.isPositiveCompletion(replyCode)) {
            return  null;
        } else {
            return ftpClient;
        }
    }

    /**
     * 获取FTP连接,默认为二进制方式
     * @param host
     * @param port
     * @param username
     * @param password
     * @return
     * @throws IOException
     */
    public static FTPClient getConnection(
            String host, int port, String username, String password) throws IOException {
        return getConnection(host,port,username,password,FTP.BINARY_FILE_TYPE);
    }
}
